package main

import (
	"fmt"
	"reflect"
)

func main01() {
	type Cat struct {
		Name string `json:"name"`
		Age  int
	}

	s := Cat{Name: "mimi", Age: 12}

	fv := reflect.ValueOf(s)
	fmt.Println(fv.String())
	fmt.Println(fv.Type().Name(), fv.Kind().String())

	for i := 0; i < fv.NumField(); i++ {
		fvfi := fv.Field(i)
		fmt.Println(fvfi.Type().Name(), fvfi.Kind().String(), fvfi.Interface())

	}

}

// todo 修改结构体字段的值：
// 前提是：必须在interface中传入结构体的指针
func main() {
	type Cat struct {
		Name string `json:"name"`
		Age  int
		Addr struct {
			Sheng string
			Shi   string
			City  string
		}
	}

	s := Cat{Name: "mimi", Age: 12}
	s.Addr.City = "shanghai"
	fvPtr := reflect.ValueOf(&s) // 获取到指针
	fvValue := fvPtr.Elem()      // 获取结构体值

	ageValue := fvValue.FieldByName("Age")

	if fvValue.CanSet() {
		//ageValue.SetInt(56)
		ageValue.Set(reflect.ValueOf(56))
		fvValue.FieldByName("Addr").FieldByName("City").SetString("上海")
	}


	fmt.Println(s)

	fmt.Println(fvValue.FieldByIndex([]int{2, 2}))

	/*

		流程：
			1、传入结构体指针
			2、ValueOf 从interface中获取结构体指针
			3、用指针值.Elem 获取结构体的值
			4、获取指定字段的值
			5、判断字段是否可修改
			6、直接set值
	*/

}



